# adjustments for using the data to control graphics prog
# * cut out insensitive region
# * remove earth gravity
# * make some keys emit only one event
# * make some keys turn on/off switches


# For onoff key handling we must store data device specific!
# We differentiate devices with a "devid" key. 
# For interactive development (TkSID) there is just one
# device and we just insert a dummy devid

# all onoff-keys should be single_keys, see below!
# single key filter *must* be applied before onoffkeyfilter
_onoff_keys = set("0123*#")
_just_one = True # only one of the onoff_keys
_on_keys_dict = {}
def _onoffkeyfilter(block):
    devid = "none"
    if "devid" in block[0]:
        devid = block[0]["devid"]
    if devid not in _on_keys_dict:
        _on_keys_dict[devid] = set()
    keys = set(block[0]["k"])
    for c in (keys & _onoff_keys): # all pressed onoff_keys
        if c in _on_keys_dict[devid]:
            _on_keys_dict[devid].remove(c)
        else:
            if _just_one:
                _on_keys_dict[devid] = set(c)
            else:
                _on_keys_dict[devid].add(c)
    keys |= _on_keys_dict[devid]
    block[0]["k"] = "".join(keys)
    return block

_single_keys = set("123456789*#ud")
def _singlekeyfilter(block):    
    entry = block[0]
    reference = block[1]
    if "k" in entry:
        entry['k'] = "".join(set(entry['k']) - (_single_keys & set(reference['k'])))
    return block

_filter_range = {'x': 0.2, 'y': 0.2, 'z': 0.2}
_filter_point = {'x': 0.0, 'y': 0.0, 'z': -1.0}
def _insensitive(block):
    entry = block[0]
    for v in "xyz":
        fp = _filter_point[v]
        fr = _filter_range[v]
        if fp-fr < entry[v] < fp+fr:
            entry[v] = fp
        else:
            # avoid jump start
            entry[v] += fr if entry[v] < fp else -fr
    return block

def _remove_gravity(block):
    # note, that now there can't be negative values 
    entry = block[0]
    entry['z'] -= _filter_point['z']
    return block

def graphicscontrol(block):
    return _onoffkeyfilter(_singlekeyfilter(_remove_gravity(_insensitive(block))))

